package gosmb

import (
	"bytes"
	"fmt"
	"net"
	"strconv"
	"time"
)

const pkt = "\x00\x00\x00\xc0\xfeSMB@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00" +
	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
	"\x00\x00\x00\x00$\x00\b\x00\x01\x00\x00\x00\u007f\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x\x00\x00\x00\x02\x00\x00\x00\x02\x02\x10\x02" +
	"\"\x02$\x02\x00\x03\x02\x03\x10\x03\x11\x03\x00\x00\x00\x00\x01\x00&\x00\x00\x00\x00" +
	"\x00\x01\x00 \x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x0e" +
	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00"

func SmbGhostScan(host string) error {
	ip, port, timeout := host, 445, 3*time.Second
	addr := fmt.Sprintf("%s:%v", host, port)
	conn, err := net.DialTimeout("tcp", addr, timeout)
	defer func() {
		if conn != nil {
			conn.Close()
		}
	}()
	if err != nil {
		return err
	}

	fmt.Println(strconv.Quote(pkt))
	_, err = conn.Write([]byte(pkt))
	if err != nil {
		return err
	}
	buff := make([]byte, 1024)
	err = conn.SetReadDeadline(time.Now().Add(timeout))
	n, err := conn.Read(buff)
	if err != nil {
		return err
	}

	fmt.Println(strconv.Quote(string(buff[:n])))

	if string(buff[68:70]) != "\x11\x03" || string(buff[70:72]) != "\x02\x00" {
		result := fmt.Sprintf("1[+] %v CVE-2020-0796 SmbGhost Vulnerable", ip)
		fmt.Println(result)
	}
	if bytes.Contains(buff[:n], []byte("Public")) == true {
		result := fmt.Sprintf("2[+] %v CVE-2020-0796 SmbGhost Vulnerable", ip)
		fmt.Println(result)

	}
	return err
}
